Imports System.IO

Namespace Controls
    <Serializable(), ObfuscationAttribute(Exclude:=True, ApplyToMembers:=True)> _
    Public Class DataGrid
        Inherits DataGridView
        Implements DataStream.IStreamRecieve, DataStream.IStreamConfig, DataStream.IStreamHandle

        Friend WithEvents cnMnuGrid As System.Windows.Forms.ContextMenuStrip
        Friend WithEvents cnGridCopyTo As System.Windows.Forms.ToolStripMenuItem
        Friend WithEvents cnGridCopy As System.Windows.Forms.ToolStripMenuItem
        Friend WithEvents cnGridPaste As System.Windows.Forms.ToolStripMenuItem
        Friend WithEvents cnGridImportFromFile As System.Windows.Forms.ToolStripMenuItem
        Friend WithEvents ToolStripSeparator10 As System.Windows.Forms.ToolStripSeparator
        Friend WithEvents cnGridInterpolate As System.Windows.Forms.ToolStripMenuItem
        Friend WithEvents cnGridInterLoad As System.Windows.Forms.ToolStripMenuItem
        Friend WithEvents cnGridInterRPM As System.Windows.Forms.ToolStripMenuItem
        Friend WithEvents cnGridEditScale As System.Windows.Forms.ToolStripMenuItem
        Friend WithEvents cnGridEditWidth As System.Windows.Forms.ToolStripMenuItem
        Friend WithEvents cnGridEditHeight As System.Windows.Forms.ToolStripMenuItem
        Friend WithEvents ToolStripSeparator8 As System.Windows.Forms.ToolStripSeparator
        Friend WithEvents cnGridMirror As System.Windows.Forms.ToolStripMenuItem
        Friend WithEvents cnGridCB As System.Windows.Forms.ToolStripMenuItem
        Friend WithEvents cnGridConfigure As System.Windows.Forms.ToolStripMenuItem

        Private m_TraceWidth As Single = 1
        Private m_TraceColour As Color = Color.Green
        Private m_TraceX As Single = -1
        Private m_TraceY As Single = -1

        Private m_EmuTraceWidth As Single = 1
        Private m_EmuTraceColour As Color = Color.Red
        Private m_EmuTracePts As Point() = Nothing

        Private m_rowDesc As String = ""
        Private m_colDesc As String = ""
        Private m_tag As New TraceTag
        Private m_newCar As CarBase = Nothing
        Private m_Table As BikiSoft.Table
        Private m_Data() As Byte

        ''' <remarks>Array of pointf's to display over the grid for a trace callback display</remarks>
        Private m_TraceOverlayPoints() As PointF = Nothing
        Private m_tracePath As Drawing2D.GraphicsPath = Nothing
        Private m_TraceOverlay As Image
        Private m_NearestOverlay As Image = Nothing
        Private m_TraceOverlayStrings() As String = Nothing

        Private WithEvents m_StreamSettings As New DataGridSettingCollection()
        Private mGetCurrentStream As DataStream.IStreamHandle.GetCurrentLog = Nothing
        Private WithEvents mStreamItems As New KeyedStringCollectionWithEvents

        Sub New()
            MyBase.New()
            Me.DefaultCellStyle = New DataGridViewCellStyle

            ' Initialise the component
            InitializeComponent()

            Me.ContextMenuStrip = Me.cnMnuGrid

            'Me.Refresh()
            Me.Invalidate()

        End Sub
        Friend Sub Clear()
            Me.Rows.Clear()
            m_TraceX = -1
            m_TraceY = -1
            m_EmuTracePts = Nothing
            m_rowDesc = ""
            m_colDesc = ""
            m_Data = Nothing
            m_Table = Nothing
            m_tag = New TraceTag
            m_TraceOverlayPoints = Nothing
        End Sub
        'NOTE: The following procedure is required by the Windows Form Designer
        'It can be modified using the Windows Form Designer.  
        'Do not modify it using the code editor.
        <System.Diagnostics.DebuggerStepThrough()> _
        Private Sub InitializeComponent()
            Me.cnMnuGrid = New System.Windows.Forms.ContextMenuStrip
            Me.cnGridCopyTo = New System.Windows.Forms.ToolStripMenuItem
            Me.cnGridCopy = New System.Windows.Forms.ToolStripMenuItem
            Me.cnGridPaste = New System.Windows.Forms.ToolStripMenuItem
            Me.cnGridImportFromFile = New System.Windows.Forms.ToolStripMenuItem
            Me.ToolStripSeparator10 = New System.Windows.Forms.ToolStripSeparator
            Me.cnGridInterpolate = New System.Windows.Forms.ToolStripMenuItem
            Me.cnGridInterLoad = New System.Windows.Forms.ToolStripMenuItem
            Me.cnGridInterRPM = New System.Windows.Forms.ToolStripMenuItem
            Me.cnGridEditScale = New System.Windows.Forms.ToolStripMenuItem
            Me.cnGridEditWidth = New System.Windows.Forms.ToolStripMenuItem
            Me.cnGridEditHeight = New System.Windows.Forms.ToolStripMenuItem
            Me.ToolStripSeparator8 = New System.Windows.Forms.ToolStripSeparator
            Me.cnGridMirror = New System.Windows.Forms.ToolStripMenuItem
            Me.cnGridCB = New System.Windows.Forms.ToolStripMenuItem
            Me.cnGridConfigure = New System.Windows.Forms.ToolStripMenuItem
            Dim DataGridViewCellStyle1 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle
            Dim DataGridViewCellStyle2 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle
            Dim DataGridViewCellStyle3 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle
            Dim DataGridViewCellStyle4 As System.Windows.Forms.DataGridViewCellStyle = New System.Windows.Forms.DataGridViewCellStyle
            Me.cnMnuGrid.SuspendLayout()
            Me.SuspendLayout()
            '
            'cnMnuGrid
            '
            Me.cnMnuGrid.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.cnGridCopyTo, Me.cnGridCopy, Me.cnGridPaste, Me.cnGridImportFromFile, Me.ToolStripSeparator10, Me.cnGridInterpolate, Me.cnGridEditScale, Me.ToolStripSeparator8, Me.cnGridMirror, Me.cnGridCB, Me.cnGridConfigure})
            Me.cnMnuGrid.Name = "cnMnuGrid"
            Me.cnMnuGrid.Opacity = 0.9
            Me.cnMnuGrid.Size = New System.Drawing.Size(197, 236)
            '
            'cnGridCopyTo
            '
            Me.cnGridCopyTo.Name = "cnGridCopyTo"
            Me.cnGridCopyTo.Size = New System.Drawing.Size(196, 22)
            Me.cnGridCopyTo.Text = "Copy To"
            '
            'cnGridCopy
            '
            Me.cnGridCopy.Name = "cnGridCopy"
            Me.cnGridCopy.ShortcutKeys = CType((System.Windows.Forms.Keys.Control Or System.Windows.Forms.Keys.C), System.Windows.Forms.Keys)
            Me.cnGridCopy.Size = New System.Drawing.Size(196, 22)
            Me.cnGridCopy.Text = "Copy"
            '
            'cnGridPaste
            '
            Me.cnGridPaste.Name = "cnGridPaste"
            Me.cnGridPaste.ShortcutKeys = CType((System.Windows.Forms.Keys.Control Or System.Windows.Forms.Keys.V), System.Windows.Forms.Keys)
            Me.cnGridPaste.Size = New System.Drawing.Size(196, 22)
            Me.cnGridPaste.Text = "Paste"
            '
            'cnGridImportFromFile
            '
            Me.cnGridImportFromFile.Name = "cnGridImportFromFile"
            Me.cnGridImportFromFile.Size = New System.Drawing.Size(196, 22)
            Me.cnGridImportFromFile.Text = "Past from file"
            '
            'ToolStripSeparator10
            '
            Me.ToolStripSeparator10.Name = "ToolStripSeparator10"
            Me.ToolStripSeparator10.Size = New System.Drawing.Size(193, 6)
            '
            'cnGridInterpolate
            '
            Me.cnGridInterpolate.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.cnGridInterLoad, Me.cnGridInterRPM})
            Me.cnGridInterpolate.Name = "cnGridInterpolate"
            Me.cnGridInterpolate.Size = New System.Drawing.Size(196, 22)
            Me.cnGridInterpolate.Text = "Interpolate Scale"
            '
            'cnGridInterLoad
            '
            Me.cnGridInterLoad.Name = "cnGridInterLoad"
            Me.cnGridInterLoad.Size = New System.Drawing.Size(144, 22)
            Me.cnGridInterLoad.Text = "Width Scale"
            '
            'cnGridInterRPM
            '
            Me.cnGridInterRPM.Name = "cnGridInterRPM"
            Me.cnGridInterRPM.Size = New System.Drawing.Size(144, 22)
            Me.cnGridInterRPM.Text = "Height Scale"
            '
            'cnGridEditScale
            '
            Me.cnGridEditScale.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.cnGridEditWidth, Me.cnGridEditHeight})
            Me.cnGridEditScale.Name = "cnGridEditScale"
            Me.cnGridEditScale.Size = New System.Drawing.Size(196, 22)
            Me.cnGridEditScale.Text = "Edit Scale"
            '
            'cnGridEditWidth
            '
            Me.cnGridEditWidth.Name = "cnGridEditWidth"
            Me.cnGridEditWidth.Size = New System.Drawing.Size(144, 22)
            Me.cnGridEditWidth.Text = "Width scale"
            '
            'cnGridEditHeight
            '
            Me.cnGridEditHeight.Name = "cnGridEditHeight"
            Me.cnGridEditHeight.Size = New System.Drawing.Size(144, 22)
            Me.cnGridEditHeight.Text = "Height Scale"
            '
            'ToolStripSeparator8
            '
            Me.ToolStripSeparator8.Name = "ToolStripSeparator8"
            Me.ToolStripSeparator8.Size = New System.Drawing.Size(193, 6)
            '
            'cnGridMirror
            '
            Me.cnGridMirror.CheckOnClick = True
            Me.cnGridMirror.Name = "cnGridMirror"
            Me.cnGridMirror.Size = New System.Drawing.Size(196, 22)
            Me.cnGridMirror.Text = "Mirrorable"
            Me.cnGridMirror.ToolTipText = "Emulator Only Option"
            '
            'cnGridCB
            '
            Me.cnGridCB.Name = "cnGridCB"
            Me.cnGridCB.Size = New System.Drawing.Size(196, 22)
            Me.cnGridCB.Text = "Toggle Control Bit"
            '
            'cnGridConfigure
            '
            Me.cnGridConfigure.Name = "cnGridConfigure"
            Me.cnGridConfigure.Size = New System.Drawing.Size(196, 22)
            Me.cnGridConfigure.Text = "Configure Find Nearest"
            '
            '
            Me.cnMnuGrid.ResumeLayout()
            Me.ResumeLayout()
        End Sub

#Region "Drawing"
        Public Property DoubleBuffering() As Boolean
            Get
                Return Me.DoubleBuffered
            End Get
            Set(ByVal value As Boolean)
                DoubleBuffered = value
            End Set
        End Property
        'Protected Overrides Sub OnCellPainting(ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs)
        '    MyBase.OnCellPainting(e)

        '    If Not IsNothing(m_EmuTracePts) AndAlso m_EmuTracePts.Length Then
        '        Dim f_rects As Rectangle = Nothing
        '        For i As Integer = 0 To UBound(m_EmuTracePts)
        '            If m_EmuTracePts(i).X = e.ColumnIndex And m_EmuTracePts(i).Y = e.RowIndex Then
        '                f_rects = Me.GetCellDisplayRectangle(m_EmuTracePts(i).X, m_EmuTracePts(i).Y, False)
        '                e.Graphics.DrawRectangle(New Pen(m_EmuTraceColour, m_EmuTraceWidth), f_rects)
        '                Return
        '            End If
        '        Next
        '    End If
        'End Sub
        Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            Dim recTrace As Rectangle = Nothing
            MyBase.OnPaint(e)
            Dim g As Graphics = e.Graphics

            ' draw trace overlay
            If Not IsNothing(m_TraceOverlayPoints) AndAlso m_TraceOverlayPoints.Length > 0 Then
                g.DrawImage(m_TraceOverlay, 0.0!, 0.0!)
            End If
            If Me.RowCount >= 1 Or Me.ColumnCount >= 1 Then
                If m_TraceX >= 0 Or m_TraceY >= 0 Then
                    If m_TraceX = -1 Then m_TraceX = 0
                    If m_TraceY = -1 Then m_TraceY = 0

                    g.Clip = New Region(e.ClipRectangle)
                    TraceDraw(g)
                End If
            End If
        End Sub

        Protected Overrides Sub OnRowPostPaint(ByVal e As System.Windows.Forms.DataGridViewRowPostPaintEventArgs)
            MyBase.OnRowPostPaint(e)
            If e.RowIndex = 0 Then DescDraw(e.Graphics)

            If Me.RowHeadersVisible Then

                Try
                    ' Paint the row number on the row header.
                    ' The using statement automatically disposes the brush.
                    If IsNothing(m_Table) Then
                        Using b As SolidBrush = _
                          New SolidBrush(Me.RowHeadersDefaultCellStyle.ForeColor)
                            e.Graphics.DrawString( _
                              Hex(e.RowIndex.ToString(System.Globalization.CultureInfo.CurrentUICulture)), _
                              New System.Drawing.Font("Courier New", 8), _
                              b, _
                              e.RowBounds.Location.X + 5, _
                              e.RowBounds.Location.Y + 4)
                        End Using

                    ElseIf Not IsNothing(m_Table) Then
                        Dim s_return() As String = m_Table.getHeightDisplay(m_Data)
                        If Not IsNothing(s_return) Then
                            Using b As SolidBrush = _
                                New SolidBrush(Me.RowHeadersDefaultCellStyle.ForeColor)
                                e.Graphics.DrawString( _
                                s_return(e.RowIndex).ToString(System.Globalization.CultureInfo.CurrentUICulture), _
                                New System.Drawing.Font("Courier New", 8), _
                                b, _
                                e.RowBounds.Location.X + 5, _
                                e.RowBounds.Location.Y + 4)
                            End Using
                        Else
                            Using b As SolidBrush = _
                            New SolidBrush(Me.RowHeadersDefaultCellStyle.ForeColor)
                                e.Graphics.DrawString( _
                                Hex((e.RowIndex * m_Table.Width).ToString), _
                                New System.Drawing.Font("Courier New", 8), _
                                b, _
                                e.RowBounds.Location.X + 5, _
                                e.RowBounds.Location.Y + 4)
                            End Using
                        End If
                    End If
                Catch
                End Try
            End If
        End Sub

        Friend Shadows Property tag() As TraceTag
            Get
                Return m_tag
            End Get
            Set(ByVal value As TraceTag)
                m_tag = value
            End Set
        End Property
        Public Sub TraceDraw()
            TraceDraw(Me.CreateGraphics)
        End Sub
        'ToDo: Verify this code displays OK
        Public Sub TraceDraw(ByVal g As Graphics)
            If Me.RowCount >= 1 And Me.ColumnCount >= 1 Then
                If m_TraceX >= 0 And m_TraceY >= 0 AndAlso _
                m_TraceX <= Me.ColumnCount - 1 And m_TraceY <= Me.RowCount - 1 Then
                    Dim recDraw As Rectangle = Me.GetCellDisplayRectangle(Math.Truncate(m_TraceX), Math.Truncate(m_TraceY), False)

                    recDraw.Offset(recDraw.Width * (m_TraceX - Math.Truncate(m_TraceX)), recDraw.Height * (m_TraceY - Math.Truncate(m_TraceY)))
                    g.DrawRectangle(New Pen(m_TraceColour, m_TraceWidth), recDraw)

                    If Not IsNothing(m_NearestOverlay) Then
                        Dim f_upperPoint As Point

                        If (m_TraceY + 1) > (Me.RowCount / 2) Then ' Bottom half
                            If (m_TraceX + 1) > Me.ColumnCount / 2 Then ' Bottom, right
                                f_upperPoint.X = recDraw.X - m_NearestOverlay.Width
                                f_upperPoint.Y = recDraw.Y - m_NearestOverlay.Height
                            Else ' Bottom, left
                                f_upperPoint.X = recDraw.X + recDraw.Width
                                f_upperPoint.Y = recDraw.Y - m_NearestOverlay.Height
                            End If
                        Else ' Top half
                            If (m_TraceX + 1) > (Me.ColumnCount / 2) Then ' Top, right
                                f_upperPoint.X = recDraw.X - m_NearestOverlay.Width
                                f_upperPoint.Y = recDraw.Y + recDraw.Height
                            Else ' Top, left
                                f_upperPoint.X = recDraw.X + recDraw.Width
                                f_upperPoint.Y = recDraw.Y + recDraw.Height
                            End If
                        End If
                        g.DrawImage(m_NearestOverlay, f_upperPoint)
                    End If

                End If

                If Not IsNothing(m_EmuTracePts) AndAlso m_EmuTracePts.Length Then
                    Dim f_rects As Rectangle()
                    ReDim f_rects(UBound(m_EmuTracePts))
                    For i As Integer = 0 To UBound(m_EmuTracePts)
                        f_rects(i) = Me.GetCellDisplayRectangle(m_EmuTracePts(i).X, m_EmuTracePts(i).Y, False)
                        f_rects(i).Inflate(1 - m_EmuTraceWidth, 1 - m_EmuTraceWidth)
                    Next
                    g.DrawRectangles(New Pen(m_EmuTraceColour, m_EmuTraceWidth), f_rects)
                End If
            End If
        End Sub
        Public Sub EmuInvalidate()
            If Me.RowCount >= 1 Or Me.ColumnCount >= 1 Then
                If Not IsNothing(m_EmuTracePts) Then
                    For i As Integer = 0 To UBound(m_EmuTracePts)
                        If m_EmuTracePts(i).X < Me.ColumnCount And m_EmuTracePts(i).Y < Me.RowCount Then
                            Me.InvalidateCell(m_EmuTracePts(i).X, m_EmuTracePts(i).Y)
                        End If
                    Next
                End If
            End If
        End Sub
        Public Sub TraceInvalidate()
            If Me.RowCount >= 1 Or Me.ColumnCount >= 1 Then
                If m_TraceX >= 0 Or m_TraceY >= 0 Then
                    If m_TraceX = -1 Then m_TraceX = 0
                    If m_TraceY = -1 Then m_TraceY = 0
                    'Invalidate this cell
                    Me.InvalidateCell(Math.Truncate(m_TraceX), Math.Truncate(m_TraceY))
                    If m_TraceX < Me.ColumnCount - 1 Then
                        Me.InvalidateCell(Math.Truncate(m_TraceX + 1), Math.Truncate(m_TraceY))
                        If m_TraceY < Me.RowCount - 1 Then
                            Me.InvalidateCell(Math.Truncate(m_TraceX + 1), Math.Truncate(m_TraceY + 1))
                        End If
                    End If
                    If m_TraceY < Me.RowCount - 1 Then
                        Me.InvalidateCell(Math.Truncate(m_TraceX), Math.Truncate(m_TraceY + 1))
                    End If
                End If
                
            End If
        End Sub
        Private Sub DescDraw(ByVal g As Graphics)
            Dim f_colFormat As New StringFormat
            Dim f_rowFormat As New StringFormat
            Dim f_font As New System.Drawing.Font("Courier New", 9, FontStyle.Regular, GraphicsUnit.Pixel)
            Using b As SolidBrush = New SolidBrush(Me.RowHeadersDefaultCellStyle.ForeColor)

                f_colFormat.LineAlignment = StringAlignment.Near ' Horiz
                f_colFormat.Alignment = StringAlignment.Far ' Vertical

                f_rowFormat.LineAlignment = StringAlignment.Far
                f_rowFormat.Alignment = StringAlignment.Near

                If m_rowDesc <> "" Then g.DrawString(m_rowDesc, f_font, b, 1, Me.ColumnHeadersHeight - 1, f_rowFormat)
                If m_colDesc <> "" Then g.DrawString(m_colDesc, f_font, b, Me.RowHeadersWidth - 1, 1, f_colFormat)
            End Using
        End Sub
        Private Sub DescDraw()
            DescDraw(Me.CreateGraphics)
        End Sub
#End Region

#Region "Properties"
        Public Property FindNearest() As Boolean
            Get
                Return Me.m_StreamSettings.FindNearest
            End Get
            Set(ByVal value As Boolean)
                Me.m_StreamSettings.FindNearest = value
            End Set
        End Property
        Public Property ColumnDescription() As String
            Get
                Return m_colDesc
            End Get
            Set(ByVal value As String)
                m_colDesc = value
                DescDraw()
            End Set
        End Property
        Public Property RowDescription() As String
            Get
                Return m_rowDesc
            End Get
            Set(ByVal value As String)
                m_rowDesc = value
                DescDraw()
            End Set
        End Property

        '<Description("Get or Set the colour of the first trace")> _
        Public Property TraceColour() As Color
            Get
                Return m_TraceColour
            End Get
            Set(ByVal value As Color)
                m_TraceColour = value
            End Set
        End Property
        ' <Description("Get or Set the X-Y co-ordinate for the trace")> _
        Public Property TracePoint() As PointF
            Get
                Return New PointF(m_TraceX, m_TraceY)
            End Get
            Set(ByVal value As PointF)
                If value.X <> m_TraceX Or value.Y <> m_TraceY Then
                    TraceInvalidate()
                    m_TraceX = value.X
                    m_TraceY = value.Y
                    If IsNothing(m_TraceOverlayStrings) Then
                        TraceDraw()
                    Else
                        m_TraceOverlayStrings = Nothing
                        Me.Invalidate()
                        TraceDraw()
                    End If
                End If
            End Set
        End Property
        Public Property TraceWidth() As Single
            Get
                Return m_TraceWidth
            End Get
            Set(ByVal value As Single)
                m_TraceWidth = value
            End Set
        End Property

        Public Property EmuTraceWidth() As Single
            Get
                Return m_EmuTraceWidth
            End Get
            Set(ByVal value As Single)
                m_EmuTraceWidth = value
            End Set
        End Property
        Public Property EmuTraceColour() As Color
            Get
                Return m_EmuTraceColour
            End Get
            Set(ByVal value As Color)
                m_EmuTraceColour = value
            End Set
        End Property
        Public Property EmuTracePoints() As Point()
            Get
                Return m_EmuTracePts
            End Get
            Set(ByVal value As Point())
                If Not value Is Nothing Then
                    If Not value.Equals(m_EmuTracePts) Then
                        EmuInvalidate()
                        m_EmuTracePts = value
                        TraceDraw()
                    End If
                End If
            End Set
        End Property

        Friend ReadOnly Property Table() As Table
            Get
                Return m_Table
            End Get
        End Property

        Friend ReadOnly Property Data() As Byte()
            Get
                Return Me.m_Data
            End Get
        End Property

        Shadows Property Item(ByVal column As Integer, ByVal row As Integer) As Controls.DataGridCell
            Get
                Return MyBase.Item(column, row)
            End Get
            Set(ByVal value As Controls.DataGridCell)
                MyBase.Item(column, row) = value
            End Set
        End Property
#End Region

#Region "Subs"

        Friend Sub ShowConfiguration()
            Dim frm As New DataStream.StreamControlSettingSelector(Me.m_StreamSettings)

            frm.ShowDialog()
        End Sub

        Friend Sub setTable(ByRef iTable As Table)
            m_Table = iTable
        End Sub
        Friend Sub setData(ByRef iData As Byte())
            m_Data = iData
        End Sub

        Friend Sub populate(ByRef iCar As CarBase, ByRef iTable As Table, ByRef iData As Byte())
            m_Table = iTable
            m_Data = iData
            m_newCar = iCar
            Me.populate()
        End Sub
        Friend Sub populate()
            Me.m_TraceOverlayStrings = Nothing
            Me.m_TraceOverlayPoints = Nothing

            If Not IsNothing(m_Table.getWidthScale.Description) Then
                Me.ColumnDescription = m_Table.getWidthScale.Description.ToolTip
            Else
                Me.ColumnDescription = ""
            End If
            If Not IsNothing(m_Table.getHeightScale.Description) Then
                Me.RowDescription = m_Table.getHeightScale.Description.ToolTip
            Else
                Me.RowDescription = ""
            End If
            If Not IsNothing(m_Table) And Not IsNothing(m_Data) Then
                Dim tm_width As Short = m_Table.Width
                Dim tm_height As Short = m_Table.Height
                Dim f_size As Byte
                Select Case (m_Table.ByteSize)
                    Case 1
                        f_size = 36
                    Case 2
                        f_size = 54
                    Case 4
                        f_size = 54
                End Select
                Dim tm_widthDisp As String() = Nothing
                If Not IsNothing(m_Table.getWidthScale) Then
                    tm_widthDisp = m_Table.getWidthDisplay(m_Data)
                End If

                If m_Table.AxisSwap Then
                    tm_width = m_Table.Height
                    tm_height = m_Table.Width
                End If

                Me.Rows.Clear()
                Me.Columns.Clear()
                'Me.RowCount = 0
                'Me.ColumnCount = 0
                Select Case m_Table.Scheme
                    Case DisplayScheme.BK_SCH_BYTE
                        If m_Table.Multiplier Mod 1 <> 0 Then
                            Me.RowsDefaultCellStyle.Format = "N1"
                            Me.AlternatingRowsDefaultCellStyle.Format = "N1"
                            Me.DefaultCellStyle.Format = "N1"
                        Else
                            Me.RowsDefaultCellStyle.Format = "N0"
                            Me.AlternatingRowsDefaultCellStyle.Format = "N0"
                            Me.DefaultCellStyle.Format = "N0"
                        End If
                    Case DisplayScheme.BK_SCH_EARLY
                        If m_Table.Multiplier Mod 1 <> 0 Then
                            Me.RowsDefaultCellStyle.Format = "N1"
                            Me.DefaultCellStyle.Format = "N1"
                            Me.AlternatingRowsDefaultCellStyle.Format = "N1"
                        Else
                            Me.RowsDefaultCellStyle.Format = "N0"
                            Me.DefaultCellStyle.Format = "N0"
                            Me.AlternatingRowsDefaultCellStyle.Format = "N0"
                        End If
                    Case DisplayScheme.BK_SCH_IGN
                        Me.RowsDefaultCellStyle.Format = "N0"
                        Me.DefaultCellStyle.Format = "N0"
                        Me.AlternatingRowsDefaultCellStyle.Format = "N0"
                    Case DisplayScheme.BK_SCH_LATE
                        If m_Table.Multiplier Mod 1 <> 0 Then
                            Me.RowsDefaultCellStyle.Format = "N1"
                            Me.DefaultCellStyle.Format = "N1"
                            Me.AlternatingRowsDefaultCellStyle.Format = "N1"
                        Else
                            Me.RowsDefaultCellStyle.Format = "N0"
                            Me.DefaultCellStyle.Format = "N0"
                            Me.AlternatingRowsDefaultCellStyle.Format = "N0"
                        End If
                    Case DisplayScheme.BK_SCH_WORD
                        Me.RowsDefaultCellStyle.Format = ""
                        Me.DefaultCellStyle.Format = ""
                        Me.AlternatingRowsDefaultCellStyle.Format = ""
                    Case Else
                        Me.RowsDefaultCellStyle.Format = ""
                        Me.DefaultCellStyle.Format = ""
                        Me.AlternatingRowsDefaultCellStyle.Format = ""
                End Select

                Me.tag.Address = m_Table.Address
                Dim colGridNew As Controls.DataGridColumn
                For i As Short = 0 To tm_width - 1
                    colGridNew = New Controls.DataGridColumn()
                    colGridNew.Name = Str(i)
                    If Not IsNothing(tm_widthDisp) Then colGridNew.HeaderText = Trim(tm_widthDisp(i))
                    Me.Columns.Add(colGridNew)
                    ' Me.Columns(i).SortMode = DataGridViewColumnSortMode.NotSortable
                    'Me.Columns(i).Width = f_size
                    'Me.Columns(i).DefaultCellStyle = New DataGridViewCellStyle(Me.DefaultCellStyle)
                Next
                Me.ColumnCount = tm_width
                Me.RowCount = tm_height

                Dim tm_x As Short
                Dim tm_y As Short
                For x As Short = 0 To m_Table.Width - 1
                    For y As Short = 0 To m_Table.Height - 1
                        tm_y = y
                        tm_x = x
                        If m_Table.HeightInvert Then tm_y = m_Table.Height - 1 - y
                        If m_Table.WidthInvert Then tm_x = m_Table.Width - 1 - x
                        If m_Table.AxisSwap Then Swap(tm_x, tm_y)
                        'Me.Item(tm_x, tm_y) = New Controls.DataGridCell()
                        'Me.Item(tm_x, tm_y).Style.Format = Me.DefaultCellStyle.Format
                        CType(Me.Item(tm_x, tm_y), Controls.DataGridCell).setData(m_Data, m_Table.Address + (y * m_Table.Width * m_Table.ByteSize) + (x * m_Table.ByteSize), m_Table)
                        'Debug.Print("Loc X:" & tm_x & "Loc Y:" & tm_y)
                    Next
                Next
            End If
            '  Catch
            'Me.RowCount = 1
            'Me.ColumnCount = 1
            'Me.Columns(0).Width = 200
            'Me.Item(0, 0) = New DataGridViewTextBoxCell
            'Me.Item(0, 0).Value = "Error displaying grid"
            'End Try
        End Sub
        Friend Sub setTraceOverlayStrings(ByVal Strings As String())
            'm_TraceOverlayStrings = Nothing
            m_TraceOverlayStrings = Strings
            Me.Refresh()
        End Sub
        Friend Sub setTracePoint(ByVal stream As DataStream.Stream)
            If Not IsNothing(stream) Then
                TracePoint = m_Table.TracePoint(m_Data, stream)
            End If
        End Sub

        ''' <summary>
        ''' Generates the Stream Nearest Overlay
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub GenerateNearestOverlay(ByVal Stream As DataStream.Stream)
            Dim names As String = ""
            Dim strs As String()

            names = BikiSoft.Table.DecodeTraceScheme(m_Table.getWidthScale.Trace) + "|"
            names += BikiSoft.Table.DecodeTraceScheme(m_Table.getHeightScale.Trace) + "|"

            For Each setting As DataGridSetting In Me.m_StreamSettings
                If setting.Visible Then
                    names += setting.Name + "|"
                End If
            Next

            strs = names.Trim("|").Split("|")

            If strs.Length > 0 Then
                ' Get Formated Values
                Dim vals(strs.Length - 1) As String
                For nCnt As Integer = 0 To vals.GetUpperBound(0)
                    If Stream.contains(strs(nCnt)) Then
                        vals(nCnt) = " = " & Stream(strs(nCnt)).FormatedValue
                    Else
                        vals(nCnt) = " = N/A"
                    End If
                Next

                Dim nameLength As Integer
                Dim valueLength As Integer
                Dim img As Bitmap = New Bitmap(Me.Bounds.Width, Me.Bounds.Height)
                Dim g As Graphics = Graphics.FromImage(img)
                Dim len As Integer
                Dim textHeight As Integer
                Dim totalWidth As Integer
                Dim totalHeight As Integer
                Dim borderWidth As Integer = 4
                Dim textSpace As Integer = 2

                For Each str As String In strs
                    len = g.MeasureString(str, New Font(Me.Font, FontStyle.Regular)).Width
                    If len > nameLength Then
                        nameLength = len
                    End If
                Next
                For Each str As String In vals
                    len = g.MeasureString(str, New Font(Me.Font, FontStyle.Regular)).Width
                    If len > valueLength Then
                        valueLength = len
                    End If
                Next

                textHeight = g.MeasureString(strs(0), New Font(Me.Font, FontStyle.Regular)).Height

                totalHeight = (borderWidth * 2) + (strs.Length * textHeight) + (strs.Length - 1 * textSpace)
                totalWidth = (borderWidth * 2) + (valueLength + nameLength)

                g.FillRectangle(New SolidBrush(Color.FromArgb(220, Color.White)), New Rectangle(0, 0, totalWidth, totalHeight))
                g.DrawRectangle(New Pen(m_TraceColour), New Rectangle(0, 0, totalWidth, totalHeight))

                g.TextContrast = 4
                Dim stringFormat As New StringFormat
                stringFormat.Alignment = StringAlignment.Far
                stringFormat.LineAlignment = StringAlignment.Near
                'stringFormat.SetTabStops(nameLength + 3, New Single() {5, 5, 5})
                g.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAliasGridFit
                Dim b As New SolidBrush(Color.Black)

                For nCnt As Integer = 0 To strs.GetUpperBound(0)
                    g.DrawString(strs(nCnt), New Font(Me.Font, FontStyle.Regular), b, borderWidth + nameLength, borderWidth + (nCnt * textHeight) + (nCnt * textSpace), stringFormat)
                Next

                stringFormat.Alignment = StringAlignment.Near
                For nCnt As Integer = 0 To vals.GetUpperBound(0)
                    g.DrawString(vals(nCnt), New Font(Me.Font, FontStyle.Regular), b, borderWidth + nameLength, borderWidth + (nCnt * textHeight) + (nCnt * textSpace), stringFormat)
                Next

                m_NearestOverlay = New Bitmap(totalWidth + 1, totalHeight + 1)

                Dim grap As Graphics = Graphics.FromImage(m_NearestOverlay)
                grap.DrawImage(img, 0, 0)
            End If
        End Sub

        ''' <summary>
        ''' Generates the Stream Overlay for the grid
        ''' </summary>
        ''' <param name="streamLog"></param>
        ''' <remarks></remarks>
        Public Sub GenerateStreamOverlay(ByVal streamLog As DataStream.StreamLog)
            If Not IsNothing(m_Table) AndAlso Not IsNothing(m_Data) AndAlso Not IsNothing(streamLog) AndAlso streamLog.Count > 0 Then
                Dim start As Integer = streamLog.RestrictStart
                Dim finish As Integer = streamLog.RestrictEnd

                If start = -1 Then start = 0
                If finish = -1 Then finish = streamLog.Count - 1

                If finish - start > 0 Then

                    ReDim m_TraceOverlayPoints(finish - start)
                    Dim highLights(Me.m_Table.AdjustedWidth - 1, Me.m_Table.adjustedHeight - 1) As Boolean

                    For nCnt As Integer = start To finish
                        m_TraceOverlayPoints(nCnt - start) = m_Table.TracePoint(m_Data, streamLog(nCnt))

                        If m_TraceOverlayPoints(nCnt - start).X = -1 Then m_TraceOverlayPoints(nCnt - start).X = 0
                        If m_TraceOverlayPoints(nCnt - start).Y = -1 Then m_TraceOverlayPoints(nCnt - start).Y = 0

                        highLights(m_TraceOverlayPoints(nCnt - start).X, m_TraceOverlayPoints(nCnt - start).Y) = True

                        m_TraceOverlayPoints(nCnt - start).X *= Me(0, 0).Size.Width
                        m_TraceOverlayPoints(nCnt - start).Y *= Me(0, 0).Size.Height

                        m_TraceOverlayPoints(nCnt - start).Y += Me.ColumnHeadersHeight * 1.5
                        m_TraceOverlayPoints(nCnt - start).X += Me.RowHeadersWidth * 1.5
                    Next

                    Try
                        ' Set the highlights
                        For col As Integer = 0 To highLights.GetUpperBound(0)
                            For row As Integer = 0 To highLights.GetUpperBound(1)
                                Me.Item(col, row).HighLight = highLights(col, row)
                            Next
                        Next
                    Catch ex As Exception

                    End Try

                    Me.m_tracePath = New Drawing2D.GraphicsPath
                    m_tracePath.FillMode = FillMode.Alternate
                    m_tracePath.AddLines(m_TraceOverlayPoints)

                    m_TraceOverlay = New Bitmap(Me.Bounds.Width, Me.Bounds.Height)
                    Dim g As Graphics = Graphics.FromImage(m_TraceOverlay)

                    g.Clear(Color.Transparent)
                    Dim p As Pen = New Pen(Color.FromArgb(80, m_TraceColour), Me(0, 0).Size.Height)
                    g.DrawPath(p, Me.m_tracePath)
                    p.Dispose()
                    g.Dispose()

                End If

                Me.Refresh()
            End If
        End Sub
        ''' <summary>
        ''' Clears the Stream overlay for the grid
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub ClearStreamOverlay()
            If Not m_TraceOverlayPoints Is Nothing Or Not m_NearestOverlay Is Nothing Then
                If Not m_TraceOverlayPoints Is Nothing Then
                    m_NearestOverlay = Nothing
                    m_TraceOverlayPoints = Nothing
                    m_tracePath.Dispose()
                End If
                m_tracePath = Nothing

                For x As Integer = 0 To Me.ColumnCount - 1
                    For y As Integer = 0 To Me.RowCount - 1
                        Me.Item(x, y).HighLight = False
                    Next
                Next
                Me.Refresh()
            End If
        End Sub
        Public Sub RecieveStream(ByVal Stream As DataStream.Stream) Implements DataStream.IStreamRecieve.RecieveStream
            ' Get the live trace
            If Not IsNothing(Me.m_Table) _
            AndAlso Not IsNothing(m_Data) Then
                TracePoint = m_Table.TracePoint(m_Data, Stream)
            End If

            ' Get the emulator trace
            If Stream.contains("EmulatorAddress") Then
                'AndAlso Stream.contains("EmulatorLast") Then
                Dim Addresses() As Double = Stream("EmulatorAddress").ValueArray
                Dim Points(Addresses.Length - 1) As Point
                Dim Count As Integer = 0

                For Each address As Double In Addresses
                    If address >= m_Table.Address _
                    AndAlso address <= m_Table.Address + m_Table.Length Then
                        address -= m_Table.Address
                        Points(Count).X = address Mod m_Table.Width
                        Points(Count).Y = address \ m_Table.Width
                        If m_Table.WidthInvert Then Points(Count).X = (m_Table.Width - 1) - Points(Count).X
                        If m_Table.HeightInvert Then Points(Count).Y = (m_Table.Height - 1) - Points(Count).Y
                        If m_Table.AxisSwap Then Swap(Points(Count))
                        Count += 1
                    End If
                Next

                ReDim Preserve Points(Count - 1)

                Me.EmuTracePoints = Points
            End If

        End Sub
#End Region

#Region "Events"

        ''' <summary>
        ''' Function handles events for KeyPress on Grids. Has a If else statement to do different EMULATOR functions and BikiRom Vairblse
        ''' </summary>
        ''' <param name="sender">dGrid or bGrid</param>
        ''' <param name="e">Event Argument</param>
        ''' <remarks>Common functions for keypress events, different handling for actual grid type handling</remarks>
        Private Sub DataGrid_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
            Dim f_add As Double
            Dim f_mult As Double
            Dim f_str As String = ""
            Dim state As Controls.DataGrid = CType(sender, DataGridView)
            Dim f_dialog As frmBDialog
            If Not IsNothing(m_Table) And Not IsNothing(m_newCar) Then
                If e.KeyChar = Chr(113) Or e.KeyChar = Chr(97) Then
                    If e.KeyChar = Chr(113) Then f_add = m_Table.Value Else f_add = -m_Table.Value
                    For Each cell As Controls.DataGridCell In state.SelectedCells
                        cell.Value += f_add
                    Next
                ElseIf e.KeyChar >= "0" And e.KeyChar <= "9" Then
                    f_dialog = New frmBDialog("Enter new value for selection", "New Value", e.KeyChar)
                    If f_dialog.ShowDialog = Windows.Forms.DialogResult.OK Then
                        f_str = f_dialog.Value
                    End If
                    ' f_str = InputBox("Enter new value for selection", "New Value", e.KeyChar)
                    If Trim(f_str) = "" Then Exit Sub
                    f_mult = Val(f_str)
                    For Each cell As Controls.DataGridCell In state.SelectedCells
                        cell.Value = f_mult
                    Next
                ElseIf e.KeyChar = Chr(42) Or e.KeyChar = Chr(45) Or e.KeyChar = Chr(43) Or e.KeyChar = Chr(47) Then
                    f_dialog = New frmBDialog("Enter new value for above operator", e.KeyChar)
                    If f_dialog.ShowDialog = Windows.Forms.DialogResult.OK Then
                        f_str = f_dialog.Value
                    End If
                    'f_str = InputBox("Enter new value for above operator", e.KeyChar)
                    If Trim(f_str) = "" Then Exit Sub
                    f_mult = Val(f_str)
                    Select Case e.KeyChar
                        Case Chr(42)
                            For Each cell As Controls.DataGridCell In state.SelectedCells
                                cell.Value *= f_mult
                            Next
                        Case Chr(45)
                            For Each cell As Controls.DataGridCell In state.SelectedCells
                                cell.Value -= f_mult
                            Next
                        Case Chr(43)
                            For Each cell As Controls.DataGridCell In state.SelectedCells
                                cell.Value += f_mult
                            Next
                        Case Chr(47)
                            If f_mult <> 0 Then
                                For Each cell As Controls.DataGridCell In state.SelectedCells
                                    cell.Value \= f_mult
                                Next
                            End If
                    End Select
                ElseIf e.KeyChar = "z" Then
                    For Each cell As Controls.DataGridCell In state.SelectedCells
                        cell.toBeSet = True
                    Next
                End If
                'm_ptTable.setTable(m_ptArray, state)
                'm_ptTable.getTable(m_ptArray, state)

                ' '' Check if the Sender grid is from dGrid or bGrid
                'If m_ptTable.EmulatorAble Then
                '    '' Do if dGrid (Normal grid) functions here
                '    Try
                '        If m_live Then
                '            Dim f_emuSetting As BVar = m_newCar.getConfig.getBikiVars.getByName("EMU")
                '            If Not IsNothing(f_emuSetting) Then
                '                Dim f_emudata As Emulator
                '                If m_MapMirror = True And m_ptTable.Mirrorable And m_ptTable.Length > 0 Then
                '                    Dim f_maps() As Table = m_newCar.getConfig.getTables.getTablesAsArray
                '                    Dim f_targetArray(f_maps.Length - 1) As Integer
                '                    Dim f_count As Int16
                '                    For Each tab As Table In f_maps
                '                        If tab = m_ptTable And tab.Mirrorable Then
                '                            f_targetArray(f_count) = tab.Address
                '                            f_count += 1
                '                        End If
                '                    Next
                '                    ReDim Preserve f_targetArray(f_count - 1)
                '                    f_emudata = New Emulator(m_ptArray, m_ptTable.Address, m_ptTable.Length, f_targetArray, f_emuSetting, 1, True)
                '                Else
                '                    f_emudata = New Emulator(m_ptArray, m_ptTable.Address, m_ptTable.Length, m_ptTable.Address, f_emuSetting, 1, True)
                '                End If

                '                If thread_CheckIfOK(threadAction.TH_EMUALTOR) Then
                '                    thread_Add(threadAction.TH_EMUALTOR)
                '                    bwEmulator.WorkerReportsProgress = True
                '                    bwEmulator.WorkerSupportsCancellation = True

                '                    bwEmulator.RunWorkerAsync(f_emudata)
                '                    Err_message(TimeOfDay & " : KeyPress Upload")
                '                Else
                '                    m_cmdQueue.Enqueue(New Threads.QueueObj(f_emudata, threadAction.TH_EMUALTOR, Nothing))
                '                End If
                '            End If
                '        End If
                '    Catch
                '        Err_message(Err.Description)
                '    Finally
                '        tmrGraph.Enabled = False
                '        tmrGraph.Enabled = True
                '    End Try
                'End If
            End If
        End Sub

        Private Sub m_StreamSettings_AfterSet(ByVal sender As Object, ByVal e As KeyedCollectionWithEventsArgs(Of DataStream.StreamControlSetting)) Handles m_StreamSettings.AfterSet
            If e.Item.Visible Then

            End If
        End Sub

        Private Sub m_StreamSettings_AfterInsert(ByVal sender As Object, ByVal e As KeyedCollectionWithEventsArgs(Of DataStream.StreamControlSetting)) Handles m_StreamSettings.AfterInsert
            If e.Item.Visible Then

            End If
        End Sub

        Private Sub m_StreamSettings_AfterClear(ByVal sender As Object, ByVal e As System.EventArgs) Handles m_StreamSettings.AfterClear

        End Sub

        Private Sub DataGrid_CellEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles Me.CellEnter
            If Me.m_StreamSettings.FindNearest AndAlso Not IsNothing(m_Data) AndAlso Not IsNothing(m_Table) AndAlso Not Me.mGetCurrentStream Is Nothing Then
                Dim StreamLog As DataStream.StreamLog = Me.mGetCurrentStream.Invoke

                If Not IsNothing(StreamLog) Then
                    Dim index As Integer = m_Table.traceFindNearestPoint(m_Data, StreamLog, New Point(e.ColumnIndex, e.RowIndex))
                    If index >= 0 And index < StreamLog.Count Then
                        '   Dim stream As DataStream.Stream = StreamLog(index)

                        RaiseEvent Seek(Me, New DataStream.StreamSeekEventArgs(index))

                    End If
                End If
            End If
        End Sub
#End Region

#Region "Interface Functions"
        Public ReadOnly Property RecieverType() As DataStream.StreamRecieveType Implements DataStream.IStreamRecieve.RecieverType
            Get
                Return DataStream.StreamRecieveType.eStreamConsumeOnly
            End Get
        End Property
        Public Event RequestRefresh(ByVal sender As Object, ByVal e As System.EventArgs) Implements DataStream.IStreamRecieve.RequestRefresh

        Public Event Restrict(ByVal sender As Object, ByVal e As DataStream.StreamRestrictEventArgs) Implements DataStream.IStreamRecieve.Restrict

        Public Event Seek(ByVal sender As Object, ByVal e As DataStream.StreamSeekEventArgs) Implements DataStream.IStreamRecieve.Seek

        Public Event Close(ByVal sender As Object, ByVal e As System.EventArgs) Implements DataStream.IStreamRecieve.Close

        Public Sub RecieveSeek(ByVal Stream As DataStream.Stream) Implements DataStream.IStreamRecieve.RecieveSeek
            If Me.m_StreamSettings.FindNearest Then
                Me.GenerateNearestOverlay(Stream)
            End If

            Me.RecieveStream(Stream)

            Me.Refresh()
        End Sub

        Public Property DataRefreshTime() As Integer Implements DataStream.IStreamConfig.DataRefreshTime
            Get
                Return 0
            End Get
            Set(ByVal value As Integer)

            End Set
        End Property

        Public Sub InitialiseValidItems(ByVal Items() As String) Implements DataStream.IStreamConfig.InitialiseValidItems
            m_StreamSettings.InitialiseValidItems(Items)
        End Sub

        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), _
        Browsable(False)> _
        Public Property StreamControlData() As Byte() Implements DataStream.IStreamConfig.StreamControlData
            Get
                If Not IsNothing(m_StreamSettings) Then
                    Dim loader As New Modules.ObjectPersistance(Of DataGridSettingCollection)
                    Dim stream As IO.Stream = Nothing

                    ' Compress and serialise
                    loader.SaveToStreamAndCompress(stream, m_StreamSettings)

                    ' Save the bytes
                    Dim bytes(stream.Length - 1) As Byte
                    stream.Read(bytes, 0, stream.Length)
                    stream.Close()
                    Return bytes
                Else
                    Return Nothing
                End If
            End Get
            Set(ByVal value As Byte())
                If Not IsNothing(value) AndAlso value.Length > 0 Then
                    Dim loader As New Modules.ObjectPersistance(Of DataGridSettingCollection)
                    Dim stream As DataGridSettingCollection = Nothing

                    ' uncompress and deserialise
                    loader.LoadFromStreamAndUnCompress(New IO.MemoryStream(value), stream)

                    If Not IsNothing(stream) Then
                        ' Set the settings and cause a Initialise
                        m_StreamSettings.Clear()

                        stream.CopyTo(m_StreamSettings)

                        '' Add old for backward compatability
                        'For Each str As String In mStreamItems
                        '    If Not mBarSettings.Contains(str) Then
                        '        mBarSettings.Add(New BarContainerSetting(str, Color.Blue, True))
                        '    End If
                        'Next

                        '    mStreamItems.Clear()

                        '  RefreshItems()
                    End If

                End If
            End Set
        End Property

        Public ReadOnly Property StreamControlItems() As KeyedStringCollectionWithEvents Implements DataStream.IStreamConfig.StreamControlItems
            Get
                Return mStreamItems
            End Get
        End Property

        Public ReadOnly Property Name1() As String Implements INamed.Name
            Get
                Return Me.Name
            End Get
        End Property

        Public Property GetCurrentStreamLog() As DataStream.IStreamHandle.GetCurrentLog Implements DataStream.IStreamHandle.GetCurrentStreamLog
            Get
                Return mGetCurrentStream
            End Get
            Set(ByVal value As DataStream.IStreamHandle.GetCurrentLog)
                mGetCurrentStream = value
            End Set
        End Property

        Public Sub RefreshLog() Implements DataStream.IStreamHandle.RefreshLog

        End Sub
#End Region

#Region "-------------------------------- Control -= Main Table Right-Click Menu event handlers"
        ''' <summary>
        ''' These functions below handle the events for the Context Menu Strip of the Main Grid component
        ''' </summary>
        Private Sub cnGridInterRPM_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cnGridInterRPM.Click
            Dim f_form As New frmInterHeight(m_newCar.getConfig.getTables, m_Table, m_newCar.Maps, m_Table.getHeightScale)
            If f_form.ShowDialog() = Windows.Forms.DialogResult.OK Then
                Me.populate()
            End If
        End Sub
        Private Sub cnGridInterLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cnGridInterLoad.Click
            Dim f_form As New frmInterScale(m_newCar.getConfig.getTables, m_Table, m_newCar.Maps, m_Table.getWidthScale)
            If f_form.ShowDialog() = Windows.Forms.DialogResult.OK Then
                Me.populate()
            End If
        End Sub
        Private Sub cnGridMirror_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cnGridMirror.Click
            If Not IsNothing(m_Table) Then m_Table.Mirrorable = cnGridMirror.Checked
        End Sub

        Private Sub cnGridCopy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cnGridCopy.Click
            Dim f_rows As Integer = 100
            Dim f_rowMax As Integer
            Dim f_colMax As Integer
            Dim f_cols As Integer = 100

            For i As Integer = 0 To Me.SelectedCells.Count - 1
                If f_rows >= Me.SelectedCells(i).RowIndex Then
                    f_rows = Me.SelectedCells(i).RowIndex
                End If
                If f_rowMax <= Me.SelectedCells(i).RowIndex Then
                    f_rowMax = Me.SelectedCells(i).RowIndex
                End If
                If f_cols >= Me.SelectedCells(i).ColumnIndex Then
                    f_cols = Me.SelectedCells(i).ColumnIndex
                End If
                If f_colMax <= Me.SelectedCells(i).ColumnIndex Then
                    f_colMax = Me.SelectedCells(i).ColumnIndex
                End If
            Next
            Debug.Print(f_colMax)
            Debug.Print(f_cols)
            Debug.Print(f_rowMax)
            Debug.Print(f_rows)

            Dim f_data((f_colMax - f_cols), (f_rowMax - f_rows)) As Double
            For x As Int16 = f_cols To f_colMax
                For y As Int16 = f_rows To f_rowMax
                    f_data(x - f_cols, y - f_rows) = Me.Item(x, y).Value
                Next
            Next

            Dim objData As New DataObject
            objData.SetData(DataFormats.Serializable, f_data)
            Clipboard.SetDataObject(objData)

        End Sub
        Private Sub cnGridPaste_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cnGridPaste.Click
            'Try
            Dim data As IDataObject = Clipboard.GetDataObject
            If Not IsNothing(Me.SelectedCells) Then
                Dim f_data(,) As Double = Nothing
                ''------------------------------------------------------------------------
                Dim f_rows As Integer = 100
                Dim f_rowMax As Integer
                Dim f_colMax As Integer
                Dim f_cols As Integer = 100

                ' This part gets the number of rows and colums selected. annoying as hell
                For i As Integer = 0 To Me.SelectedCells.Count - 1
                    If f_rows >= Me.SelectedCells(i).RowIndex Then
                        f_rows = Me.SelectedCells(i).RowIndex
                    End If
                    If f_rowMax <= Me.SelectedCells(i).RowIndex Then
                        f_rowMax = Me.SelectedCells(i).RowIndex
                    End If
                    If f_cols >= Me.SelectedCells(i).ColumnIndex Then
                        f_cols = Me.SelectedCells(i).ColumnIndex
                    End If
                    If f_colMax <= Me.SelectedCells(i).ColumnIndex Then
                        f_colMax = Me.SelectedCells(i).ColumnIndex
                    End If
                Next
                '--------------------------------------------------------------------------

                If data.GetDataPresent(DataFormats.Serializable) Then
                    f_data = data.GetData(DataFormats.Serializable)
                    'Dim f_Clipdata As States.Biki_Clipboard = DirectCast(data.GetData("States.Biki_Clipboard"), States.Biki_Clipboard)
                    'f_data = f_Clipdata.Data
                    For Each s_cell As Controls.DataGridCell In Me.SelectedCells
                        If s_cell.RowIndex - f_rows <= f_data.GetUpperBound(1) AndAlso _
                            s_cell.ColumnIndex - f_cols <= f_data.GetUpperBound(0) Then
                            s_cell.Value = f_data(s_cell.ColumnIndex - f_cols, s_cell.RowIndex - f_rows)
                        End If
                    Next
                    'Debug.Print(f_Clipdata.Name)
                ElseIf data.GetDataPresent(DataFormats.CommaSeparatedValue) Then '-------- Comma Deliminated!
                    Dim srReadExcel As New StreamReader(CType(data.GetData(DataFormats.CommaSeparatedValue), Stream))
                    Dim f_str() As String

                    Dim f_count As Integer
                    Dim sFormattedData As String

                    While (srReadExcel.Peek() > 0)
                        sFormattedData = srReadExcel.ReadLine()
                        f_str = sFormattedData.Split(",")
                        ReDim Preserve f_data(f_str.GetUpperBound(0), f_count)
                        For i As Short = 0 To f_str.GetUpperBound(0)
                            f_data(i, f_count) = Val(f_str(i))
                        Next
                        f_count += 1
                    End While
                    For Each s_cell As Controls.DataGridCell In Me.SelectedCells
                        If s_cell.RowIndex - f_rows <= f_data.GetUpperBound(1) Then
                            If s_cell.ColumnIndex - f_cols <= f_data.GetUpperBound(0) Then
                                s_cell.Value = f_data(s_cell.ColumnIndex - f_cols, s_cell.RowIndex - f_rows)
                            End If
                        End If
                    Next
                Else
                    Err_message("Clipboard Data isn't valid")
                    Exit Sub
                End If
                Me.populate()
            End If
            'Catch ex As Exception
            'Err_message("Error in Pasting operation")
            'End Try
        End Sub
        Private Sub cnGridCB_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cnGridCB.Click
            If Not IsNothing(m_newCar) Then
                If Not IsNothing(m_Table) Then
                    For Each cell As Controls.DataGridCell In Me.SelectedCells
                        cell.toBeSet = True
                    Next
                End If
            End If
        End Sub
        Private Sub cnGridEditWidth_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cnGridEditWidth.Click
            If Not IsNothing(m_Table) And Not IsNothing(m_newCar) Then
                Dim f_scale As Scale = m_Table.getWidthScale
                If Not IsNothing(f_scale) Then
                    If IsNothing(f_scale.maxVar) Or IsNothing(f_scale.minVar) Then
                        '' Treat as normal scale
                        If f_scale.Address > 0 Then
                            Dim f_str As String = m_Table.Name
                            If Not IsNothing(f_scale.Description) Then f_str &= " - " & f_scale.Description.Description
                            m_Table = New Table(f_scale.Address, m_Table.AdjustedWidth, 1, f_str)
                            m_Table.setAxis(False, False, False, DisplayMode.BK_DISP_ADJUSTED, DisplayScheme.BK_SCH_BYTE)
                            m_Table.setDisplay(f_scale.Multiplier, f_scale.preDivider, f_scale.Offset, 0)
                            m_Table.Name = f_str & " - " & f_scale.Description.Description
                            Me.populate()
                        End If
                    ElseIf Not IsNothing(f_scale.maxVar) And Not IsNothing(f_scale.minVar) Then
                        ' ToDo: Repair
                        'Dim f_vars As New Vars("Scale Mininum and Maximum Values (range)")
                        'f_vars.addNode(New Var() {f_scale.minVar, f_scale.maxVar})
                        'If Not IsNothing(m_newCar.getBikSettings.getData) Then
                        '    m_Data = m_newCar.getBikSettings.getData
                        '    m_ptVars = f_vars
                        '    global_populate(m_ptVars)
                        '    boxGlobal.Text = f_vars.Description
                        '    boxGlobal.Visible = True
                        'End If
                    End If
                End If
            End If
        End Sub
        Private Sub cnGridEditHeight_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cnGridEditHeight.Click
            If Not IsNothing(m_Table) And Not IsNothing(m_newCar) Then
                Dim f_scale As Scale = m_Table.getHeightScale
                If Not IsNothing(f_scale) Then
                    If IsNothing(f_scale.maxVar) Or IsNothing(f_scale.minVar) Then
                        '' Treat as normal scale
                        If f_scale.Address > 0 Then
                            Dim f_str As String = m_Table.Name
                            If Not IsNothing(f_scale.Description) Then f_str &= " - " & f_scale.Description.Description
                            m_Table = New Table(f_scale.Address, 1, m_Table.adjustedHeight, f_str)
                            m_Table.setAxis(False, False, False, DisplayMode.BK_DISP_ADJUSTED, DisplayScheme.BK_SCH_BYTE)
                            m_Table.setDisplay(f_scale.Multiplier, f_scale.preDivider, f_scale.Offset, 0)
                            m_Table.Name = f_str & " - " & f_scale.Description.Description
                            Me.populate()
                        End If
                    ElseIf Not IsNothing(f_scale.maxVar) And Not IsNothing(f_scale.minVar) Then
                        ' ToDo: Repair
                        'Dim f_vars As New Vars("Scale Mininum and Maximum Values (range)")
                        'f_vars.addNode(New Var() {f_scale.minVar, f_scale.maxVar})
                        'If Not IsNothing(m_newCar.getBikSettings.getData) Then
                        '    m_Data = m_newCar.getBikSettings.getData
                        '    m_ptVars = f_vars
                        '    boxGlobal.Text = f_vars.Description
                        '    global_populate(m_ptVars)
                        '    box_hideAll()
                        '    boxGlobal.Visible = True
                        'End If
                    End If
                End If
            End If
        End Sub
        Private Sub cnGridImportFromFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cnGridImportFromFile.Click
            Dim openBin As New OpenFileDialog()
            If Not IsNothing(m_newCar) Then
                openBin.Title = "Select csv file containing new Table Values"
                openBin.InitialDirectory = Application.StartupPath & "\Tables\"
                openBin.Filter = "*.csv Comma Seperated File|*.csv"
                If openBin.ShowDialog = Windows.Forms.DialogResult.OK Then
                    Dim f_fStream As New FileStream(openBin.FileName, FileMode.Open)
                    Dim f_streamReader As New StreamReader(f_fStream)
                    Dim f_str As String = f_streamReader.ReadLine
                    f_fStream.Close()
                    f_streamReader.Close()
                    Dim f_strs() As String = f_str.Split(",")

                    If f_strs.Length > (m_Table.Width * m_Table.Height) Then
                        For i As Integer = 0 To f_strs.Length - 1
                            m_Table.setValue(m_Data, i, Val(f_strs(i)))
                        Next
                    Else
                        For i As Integer = 0 To (m_Table.Width * m_Table.Height) - 1
                            m_Table.setValue(m_Data, i, Val(f_strs(i)))
                        Next
                    End If

                    Me.populate()
                End If
            End If
        End Sub
        Private Sub cnGridConfigure_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cnGridConfigure.Click
            Me.ShowConfiguration()
        End Sub
        Private Sub cnMnuGrid_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles cnMnuGrid.Opening
            If Clipboard.GetDataObject.GetDataPresent(DataFormats.Serializable) Or _
              Clipboard.GetDataObject.GetDataPresent(DataFormats.CommaSeparatedValue) Then
                cnGridPaste.Enabled = True
            Else
                cnGridPaste.Enabled = False
            End If
            If Not IsNothing(m_Table) Then cnGridMirror.Checked = m_Table.Mirrorable
            cnGridCopyTo.DropDownItems.Clear()
            If Not IsNothing(m_newCar) Then
                Dim f_count As Integer = 0

                If m_Table.widthEditable Then cnGridEditWidth.Enabled = True Else cnGridEditWidth.Enabled = False
                If m_Table.heightEditable Then cnGridEditHeight.Enabled = True Else cnGridEditHeight.Enabled = False

                Dim f_matches(m_newCar.getConfig.getTables.countTotal) As ToolStripMenuItem
                Dim image_ As System.Drawing.Image = Nothing
                f_count = 0
                If Not IsNothing(m_newCar.getConfig.getTables) Then
                    If Not IsNothing(m_newCar.getConfig.getTables.getAsArray) Then
                        For Each f_tableCont As TableCont In m_newCar.getConfig.getTables.getAsArray
                            If Not IsNothing(f_tableCont.getAsArray) Then
                                For Each f_table As Table In f_tableCont.getAsArray
                                    If m_Table = f_table Then
                                        f_matches(f_count) = New ToolStripMenuItem(f_table.Name & " - " & _
                                        f_table.Description.Description, image_, AddressOf cnGridCopyToItem_Click)
                                        f_matches(f_count).Tag = f_table.Address
                                        f_count += 1
                                    End If
                                Next
                            End If
                        Next
                    End If
                End If
                If f_count = 0 Then
                    cnGridCopyTo.DropDownItems.Add("no matching maps..")
                    Exit Sub
                End If
                ReDim Preserve f_matches(f_count - 1)
                cnGridCopyTo.DropDownItems.AddRange(f_matches)
            End If
        End Sub
        Private Sub cnGridCopyToItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
            Dim mnuItem As ToolStripMenuItem = CType(sender, ToolStripMenuItem)

            If Not IsNothing(m_newCar) And Not IsNothing(m_Data) And mnuItem.Tag <> 0 Then
                Dim f_table As Table = m_newCar.getConfig.getTables.getTableByAddress(mnuItem.Tag)
                If Not IsNothing(f_table) Then
                    f_table.setRaw(m_Data, m_Table.getRaw(m_Data))
                End If
            End If
        End Sub
#End Region

    End Class
End Namespace
